package com.fowo.api.documentCirculation.sql;

import org.springframework.util.StringUtils;

/**
 * SqlServer 语法处理器
 * @author yl_ls
 */
public class SqlServerHandler extends AbsoluteSqlHandler {
    @Override
    String safeName(String name) {
        if (name.startsWith("[")) {
            return name;
        }
        return "[" + name + "]";
    }

    @Override
    public String funcIf(String conditionExp, String trueExp, String falseExp) {
        return String.format("IIF(%s, %s, %s)", conditionExp, trueExp, falseExp);
    }

    @Override
    public String funcIfNull(String valueExp, String nullExp) {
        return String.format("ISNULL(%s, %s)", valueExp, nullExp);
    }

    @Override
    public SqlAndArgs createSelectSql(SqlBuilder sqlBuilder) {
        if (sqlBuilder.getSkip() != null && sqlBuilder.getSkip() > 0 ||
                sqlBuilder.getLimit() != null && sqlBuilder.getLimit() > 0
        ) {
            int skip = sqlBuilder.getSkip() == null ? 0 : sqlBuilder.getSkip();
            int limit = sqlBuilder.getLimit() == null ? 0 : sqlBuilder.getLimit();
            SqlAndArgs sqlAndArgs = new SqlAndArgs();
            StringBuilder sb = new StringBuilder();
            sb.append("SELECT * FROM (");
            appendSelectStart(sb, sqlBuilder);
            sb.append("SELECT ROW_NUMBER() OVER(ORDER BY ");
            if (sqlBuilder.getGroupBys().isEmpty()) {
                if (StringUtils.hasText(sqlBuilder.getAsName())) {
                    sb.append(safeName(sqlBuilder.getAsName())).append(".");
                }
                sb.append("id");
            } else {
                sb.append(sqlBuilder.getGroupBys().get(0));
            }
            sb.append(") AS RowNumber,");
            appendSelectColumns(sb, sqlBuilder);
            sb.append(" ");
            sb.append("FROM ");
            sb.append(safeName(sqlBuilder.getTable()));
            if (StringUtils.hasText(sqlBuilder.getAsName())) {
                sb.append(" AS ").append(safeName(sqlBuilder.getAsName()));
            }
            appendJoinsSql(sb, sqlBuilder, sqlAndArgs);
            appendWhereSql(sb, sqlBuilder, sqlAndArgs);
            appendGroupBySql(sb, sqlBuilder, sqlAndArgs);
            appendSelectEnd(sb, sqlBuilder);
            sb.append(String.format(") AS _P WHERE _P.RowNumber BETWEEN %d AND %d ORDER BY _P.id", skip + 1, limit + skip));
            sqlAndArgs.setSql(sb.toString());
            return sqlAndArgs;
        }
        return super.createSelectSql(sqlBuilder);
    }

    @Override
    protected void appendConvertToStringEnd(StringBuilder sb) {
        sb.append(" AS VARCHAR(20))");
    }

    @Override
    protected void appendConvertToStringStart(StringBuilder sb) {
        sb.append("CAST(");
    }

    @Override
    public SqlAndArgs getSelectExistsSql(SqlBuilder sqlBuilder) throws Exception {
        SqlAndArgs sqlAndArgs = getSql(sqlBuilder);
        sqlAndArgs.setSql(String.format("SELECT iif(EXISTS (%s), 1, 0)", sqlAndArgs.getSql()));
        return sqlAndArgs;
    }

    @Override
    public String getNewIdentitySql() {
        return "SELECT @@IDENTITY";
    }
}
